Skip to content

Conversation

@hexbabe
Copy link
Member

@hexbabe hexbabe commented Nov 17, 2025

Tests on linux/arm64 (rpi5b)

  • Unplug replug
  • Reconfigure (new video_path and resolution)
  • find-webcams adding a new camera

In fact, this PR fixed an unreported linux bug too (unplug/replug is not working on linux/arm64 on the main branch).

Tests on darwin/arm64 (viam issued macbook air laptop)

  • Unplug replug
  • Reconfigure (new video_path and resolution)
  • find-webcams adding a new camera

@viambot viambot added the safe to test This pull request is marked safe to test from a trusted zone label Nov 17, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Nov 17, 2025
@hexbabe hexbabe marked this pull request as ready for review November 25, 2025 15:37
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Dec 1, 2025
c.buffer.frame = nil
// Make a private copy of the previously published frame so consumers can continue to read it,
// then return the Reader-managed buffer before we kick off the next read. This avoids holding
// on to driver memory while still serving the last frame.
Copy link
Member Author

@hexbabe hexbabe Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introducing prevRelease fixes the hang. All other changes on this PR are to supplement it, to ensure best practices, and fix vulnerabilities in the code I saw along the way of fixing the hang.

@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Dec 1, 2025
}

// Must lock the mutex before using this function.
func (buffer *WebcamBuffer) stopBuffer() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hate how buffer is used to group together the actual buffer and the worker that fills it. I made a lot of changes to fix that naming and also deleted this helper function that is frankly a bit confusing.

c.buffer.worker.Stop() // Calling this before locking shuts down the goroutines, and allows stopBuffer() to handle rest of the shutdown.

// Stop the driver and frame buffer worker
c.mu.Lock()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this shouldn't be an AlwaysRebuild resource? Seems like that may simplify things but lmk if im missing something

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm 90% sure it could be one. Would just be a rather big change.

) (video.Reader, driverutils.Driver, string, error) {
mediadevicescamera.Initialize()
if runtime.GOOS == "linux" {
// TODO(RSDK-12789): Separate discover() calls from Initialize() calls.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to wait on RSDK-12789 before merging? How does initialization happen on darwin?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, it'll work this way, just not my favorite way to "refresh" cameras by calling a function named Initialize that is only supposed to handle initialization

Copy link
Member Author

@hexbabe hexbabe Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does initialization happen on darwin?

The answer to this question is complicated and I would prefer to explain it in person

var prevRelease func()
c.mu.Lock()
if c.buffer.release != nil && c.buffer.frame != nil {
c.buffer.frame = rimage.CloneImage(c.buffer.frame)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we are making a private copy on every frame here? Is perf an issue?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point. Let me profile and look into alternatives

@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Dec 2, 2025

if conf.Width != 0 && conf.Height != 0 {
if img.Bounds().Dx() != conf.Width || img.Bounds().Dy() != conf.Height {
return nil, nil, "", errors.Errorf("requested width and height (%dx%d) are not available for this webcam"+
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just warning log here and succeed if dimensions do not exactly match?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test This pull request is marked safe to test from a trusted zone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants